package com.mtsoft.mfkernel;

import java.util.regex.Pattern;

/**
 *
 * @author Mark
 */
public class FieldUtil {
    private static Pattern signedDecimal = Pattern.compile("(-?)(\\d){1,10}\\.(\\d){1,10}");
    private static Pattern signedInteger = Pattern.compile("(-?)(\\d){1,10}");
    private static Pattern signedIntegerDot = Pattern.compile("(-?)(\\d){1,10}\\.");
    private static Pattern signed = Pattern.compile("(-?)");

    /**
     *
     * @param field
     * @param text
     * @return
     */
    public static boolean validateField(Field field, String text){
        boolean valid = true;
        if("".equals(text) || field.getStorageType() == StorageType.ALPHA) {
            valid = text.length() <= field.getStorageLength();
            return valid;
        }
        valid = signed.matcher(text).matches() || signedInteger.matcher(text).matches();
        if(field.getScale() != 0) {
            valid = valid || signedDecimal.matcher(text).matches()
                    || signedIntegerDot.matcher(text).matches();
        }
        if(valid) {
            if(text.startsWith("-")) {
                text = text.substring(1);
            }
            String[] parts = text.split("\\.");
            if(parts[0].length() > field.getLength() - field.getScale()) {
                valid = false;
            }
            if(parts.length == 2 && parts[1].length() > field.getScale()) {
                valid = false;
            }
        }
        return valid;
    }

    public static String formatStringToBytes(Field field, String string) {
        String retVal;
        if(field.getStorageType() == StorageType.ALPHA) {
            StringBuilder sb = new StringBuilder(string);
            if(sb.length() > field.getStorageLength()) {
                sb.delete(field.getStorageLength(), sb.length());
            } else {
                while(sb.length() < field.getStorageLength()) {
                    sb.append(" ");
                }
            }
            retVal = sb.toString();
        } else {
            if(field.getScale() > 0) {
                retVal = formatDecimal(string, field.getStorageLength(), field.getScale());
            } else {
                retVal = formatNumeric(string, field.getStorageLength());
            }
        }
        return retVal;
    }

    public static String formatNumeric(String string, int length) {
        StringBuilder buffer = new StringBuilder(string);
        int insert = 0;
        if(buffer.charAt(0) == '-')
            insert = 1;
        while(buffer.length() < length + insert) {
            buffer.insert(insert, "0");
        }
        return buffer.toString();
    }

    public static String formatDecimal(String string, int length, int scale) {
        boolean negative = false;
        // store the sign
        if(string.startsWith("-")) {
            string = string.substring(1, string.length());
            negative = true;
        }
        // set up a and b:
        int dot = string.indexOf(".");
        int a = (length - scale) - dot;
        int b = (length - scale) + (string.length() - dot);
        // remove the dot
        StringBuilder buffer = new StringBuilder(string);
        buffer.deleteCharAt(dot);
        // pad left and right with zeroes
        boolean left = true, right = true;
        while(left || right) {
            if(left && a > 0) {
                buffer.insert(0, "0");
                a--;
            } else {
                left = false;
            }
            if(right && b <= length) {
                buffer.append("0");
                b++;
            } else {
                right = false;
            }
        }
        if(negative)
            buffer.insert(0, "-");
        return buffer.toString();
    }

    public static String formatStringToDisplay(Field field, String string) {
        return "";
    }

    /**
     * Text for fields is validated so I know they are valid numbers. The
     * load/store routines pad to the left, I just have to remove '.' and
     * pad to the right.  Also leave '-' as those are taken care of too.
     *
     * @param field
     * @param text
     * @return
     */
    public static String formatField(Field field, String text) {
        StringBuilder buffer = new StringBuilder(text);
        if(field.getStorageType() == StorageType.ALPHA) {
            while(buffer.length() < field.getStorageLength()) {
                buffer.append(" ");
            }
        } else {
            if(field.getScale() > 0) {
                // pad zeroes on right
                String[] parts = text.split("\\.");
                int zeroes = field.getScale();
                if(parts.length == 2) {
                    zeroes = field.getScale() - parts[1].length();
                }
                while(zeroes > 0) {
                    buffer.append("0");
                    zeroes--;
                }
                // remove '.'
                int dot = buffer.indexOf(".");
                if(dot > 0)
                    buffer.deleteCharAt(dot);
            }
        }
        return buffer.toString();
    }
}
